์น ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ์ ๋ํ ํฌ๊ด์ ์ธ ๊ฐ์ด๋. ์ปค์คํ ์๋ฆฌ๋จผํธ ์์ฑ, ์์ฑ ๊ด๋ฆฌ, ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ UI ์ปดํฌ๋ํธ ๊ตฌ์ถ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ค๋ฃน๋๋ค.
์น ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ: ์ปค์คํ ์๋ฆฌ๋จผํธ ์์ฑ ๋ฐ ๊ด๋ฆฌ
์น ์ปดํฌ๋ํธ๋ ๊ฐ๋ฐ์๊ฐ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๊ณ , ์บก์ํ๋์์ผ๋ฉฐ, ์ํธ ์ด์ฉ ๊ฐ๋ฅํ ์ปค์คํ HTML ์๋ฆฌ๋จผํธ๋ฅผ ๋ง๋ค ์ ์๊ฒ ํด์ฃผ๋ ๊ฐ๋ ฅํ ์น ํ์ค ๊ธฐ์ ๋ชจ์์ ๋๋ค. ์ด๋ฌํ ์ปดํฌ๋ํธ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ดํดํ๋ ๊ฒ์ ๊ฒฌ๊ณ ํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ด ์ข ํฉ ๊ฐ์ด๋์์๋ ์น ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ์ ๋ค์ํ ๋จ๊ณ๋ฅผ ์์ธํ ์ดํด๋ณด๊ณ , ์ค์ฉ์ ์ธ ์์ ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค.
์น ์ปดํฌ๋ํธ๋ ๋ฌด์์ธ๊ฐ?
์น ์ปดํฌ๋ํธ๋ ์บก์ํ๋ ์คํ์ผ๊ณผ ๋ก์ง์ ๊ฐ์ง ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปค์คํ HTML ์๋ฆฌ๋จผํธ๋ฅผ ๋ง๋ค ์ ์๋ ๊ธฐ์ ๋ชจ์์ ๋๋ค. ์ด๋ ์ธ ๊ฐ์ง ์ฃผ์ ์ฌ์์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค:
- ์ปค์คํ ์๋ฆฌ๋จผํธ(Custom Elements): ์ฌ์ฉ์ ์ ์ ๊ธฐ๋ฅ์ ๊ฐ์ง ์์ ๋ง์ HTML ์๋ฆฌ๋จผํธ๋ฅผ ์ ์ํฉ๋๋ค.
- ์๋ DOM(Shadow DOM): ์ปดํฌ๋ํธ์ ๋ด๋ถ ๊ตฌ์กฐ, ์คํ์ผ, ๋์์ ์บก์ํํ์ฌ ์ฃผ๋ณ ๋ฌธ์์์ ๊ฐ์ญ์ ๋ฐฉ์งํฉ๋๋ค.
- HTML ํ ํ๋ฆฟ(HTML Templates): ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ HTML ๋งํฌ์ ๋ฉ์ด๋ฆฌ๋ฅผ ์ ์ํ ์ ์๊ฒ ํด์ค๋๋ค.
์ด๋ฌํ ๊ธฐ์ ๋ค์ ํตํด ๊ฐ๋ฐ์๋ค์ ๊ธฐ๋ฐ ํ๋ ์์ํฌ์ ๊ด๊ณ์์ด ๋ชจ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฝ๊ฒ ํตํฉํ ์ ์๋ ๋ ๋ฆฝ์ ์ด๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ UI ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ ๋ ฌ, ํํฐ๋ง, ํ์ด์ง๋ค์ด์ ์ ์ฒ๋ฆฌํ๋ ์ปค์คํ <data-grid> ์๋ฆฌ๋จผํธ๋, ์ ์ธ๊ณ ๊ตญ๊ฐ ๋ชฉ๋ก์์ ์ฌ์ฉ์๊ฐ ํธ๋ฆฌํ๊ฒ ๊ตญ๊ฐ๋ฅผ ์ ํํ ์ ์๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ <country-selector> ์๋ฆฌ๋จผํธ๋ฅผ ๋ง๋ ๋ค๊ณ ์์ํด ๋ณด์ธ์. ์น ์ปดํฌ๋ํธ๋ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
์น ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ
์น ์ปดํฌ๋ํธ์ ์๋ช ์ฃผ๊ธฐ๋ ์์ฑ๋ถํฐ ์ ๊ฑฐ๊น์ง ์ปดํฌ๋ํธ๊ฐ ์กด์ฌํ๋ ๋ค์ํ ๋จ๊ณ๋ฅผ ์ค๋ช ํฉ๋๋ค. ์ด ๋จ๊ณ๋ค์ ์ดํดํ๋ฉด ํน์ ์ด๋ฒคํธ์ ์ฐ๊ฒฐํ์ฌ ์ปดํฌ๋ํธ์ ๋์๊ณผ ์ํ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐ ํ์ํ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
๋ค ๊ฐ์ง ํต์ฌ ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
connectedCallbackdisconnectedCallbackattributeChangedCallbackadoptedCallback
1. connectedCallback
connectedCallback์ ์ปค์คํ
์๋ฆฌ๋จผํธ๊ฐ ๋ฌธ์์ DOM์ ์ฐ๊ฒฐ๋ ๋ ํธ์ถ๋ฉ๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ฆฌ๋จผํธ๊ฐ ๋ฌธ์์ ์ถ๊ฐ๋๊ฑฐ๋ ๋ฌธ์์ ํ ๋ถ๋ถ์์ ๋ค๋ฅธ ๋ถ๋ถ์ผ๋ก ์ด๋ํ ๋ ๋ฐ์ํฉ๋๋ค. ์ด ์์ ์ ๋ค์ ์์
์ ์ํํ๊ธฐ์ ์ด์์ ์ธ ๊ณณ์
๋๋ค:
- ์ปดํฌ๋ํธ์ ์ํ ์ด๊ธฐํ
- ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋ถ์ฐฉ
- ์ธ๋ถ ์์ค์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
- ์ปดํฌ๋ํธ์ ์ด๊ธฐ UI ๋ ๋๋ง
์์ :
class MyComponent extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.shadow.innerHTML = `
<style>
:host {
display: block;
border: 1px solid #ccc;
padding: 10px;
}
</style>
<p>Hello from MyComponent!</p>
`;
// Example of fetching data (replace with your actual API endpoint)
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
// Process the data and update the component's UI
const dataElement = document.createElement('p');
dataElement.textContent = `Data: ${JSON.stringify(data)}`;
this.shadow.appendChild(dataElement);
});
}
}
customElements.define('my-component', MyComponent);
์ด ์์ ์์ connectedCallback์ ์ปดํฌ๋ํธ์ ์๋ DOM์ ๋ถ์ฐฉํ๊ณ , ์ด๊ธฐ HTML์ ๋ ๋๋งํ๋ฉฐ, ์ธ๋ถ API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ก ์๋ DOM์ ์
๋ฐ์ดํธํฉ๋๋ค.
2. disconnectedCallback
disconnectedCallback์ ์ปค์คํ
์๋ฆฌ๋จผํธ๊ฐ ๋ฌธ์์ DOM์์ ์ฐ๊ฒฐ ํด์ ๋ ๋ ํธ์ถ๋ฉ๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ฆฌ๋จผํธ๊ฐ ๋ฌธ์์์ ์ ๊ฑฐ๋๊ฑฐ๋ ๋ค๋ฅธ ๋ฌธ์๋ก ์ด๋ํ ๋ ๋ฐ์ํฉ๋๋ค. ์ด ์์ ์ ๋ค์ ์์
์ ์ํํ๊ธฐ์ ์ด์์ ์ธ ๊ณณ์
๋๋ค:
- ๋ฆฌ์์ค ์ ๋ฆฌ
- ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ๊ฑฐ
- ๋๊ธฐ ์ค์ธ ์์ฒญ ์ทจ์
์์ :
class MyComponent extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
this.eventListener = null; // Store the event listener
}
connectedCallback() {
// ... (previous code) ...
// Example: Add a resize event listener
this.eventListener = () => {
console.log('Component resized!');
};
window.addEventListener('resize', this.eventListener);
}
disconnectedCallback() {
// Remove the resize event listener
if (this.eventListener) {
window.removeEventListener('resize', this.eventListener);
this.eventListener = null;
}
console.log('Component disconnected!');
}
}
์ด ์์ ์์ disconnectedCallback์ connectedCallback์์ ์ถ๊ฐ๋ ๋ฆฌ์ฌ์ด์ฆ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ ๊ฑฐํ์ฌ, ์ปดํฌ๋ํธ๊ฐ DOM์์ ์ ๊ฑฐ๋ ํ ๋ฐ์ํ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ ๋์๋ ์๊ธฐ์น ์์ ๋์์ ๋ฐฉ์งํฉ๋๋ค.
3. attributeChangedCallback
attributeChangedCallback์ ์ปค์คํ
์๋ฆฌ๋จผํธ์ ๊ด์ฐฐ ๋์ ์์ฑ ์ค ํ๋๊ฐ ์ถ๊ฐ, ์ ๊ฑฐ, ์
๋ฐ์ดํธ ๋๋ ๊ต์ฒด๋ ๋ ํธ์ถ๋ฉ๋๋ค. ์์ฑ์ ๊ด์ฐฐํ๋ ค๋ฉด ์ปค์คํ
์๋ฆฌ๋จผํธ ํด๋์ค์ ์ ์ observedAttributes getter๋ฅผ ์ ์ํด์ผ ํฉ๋๋ค. ์ด ์ฝ๋ฐฑ์ ์ปดํฌ๋ํธ ๊ตฌ์ฑ์ ๋ณํ์ ๋์ํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์์ :
class MyComponent extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
}
static get observedAttributes() {
return ['message', 'country'];
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`Attribute ${name} changed from ${oldValue} to ${newValue}`);
if (name === 'message') {
this.shadow.querySelector('p').textContent = newValue;
} else if (name === 'country') {
//Imagine fetching flag image based on the selected country code
let flagURL = `https://flagcdn.com/w40/${newValue}.png`;
let img = this.shadow.querySelector('img');
if(!img){
img = document.createElement('img');
this.shadow.appendChild(img);
}
img.src = flagURL;
img.alt = `Flag of ${newValue}`;
}
}
connectedCallback() {
this.shadow.innerHTML = `
<style>
:host {
display: block;
border: 1px solid #ccc;
padding: 10px;
}
</style>
<p>Hello from MyComponent!</p>
<img style="width:40px;"/>
`;
// Set initial message from attribute if it exists
if (this.hasAttribute('message')) {
this.shadow.querySelector('p').textContent = this.getAttribute('message');
}
}
}
customElements.define('my-component', MyComponent);
์ด ์์ ์์ ์ปดํฌ๋ํธ๋ message์ country ์์ฑ์ ๊ด์ฐฐํฉ๋๋ค. message ์์ฑ์ด ๋ณ๊ฒฝ๋๋ฉด attributeChangedCallback์ ์๋ DOM ๋ด์ p ์๋ฆฌ๋จผํธ์ ํ
์คํธ ์ฝํ
์ธ ๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค. country ์์ฑ์ด ๋ณ๊ฒฝ๋๋ฉด ํด๋น ๊ตญ๊ฐ์ ๊ตญ๊ธฐ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ `img` ์๋ฆฌ๋จผํธ๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค.
์ด ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด HTML์ ์์ฑํฉ๋๋ค:
<my-component message="Hello World!" country="gb"></my-component>
๊ทธ๋ฐ ๋ค์ JavaScript๋ฅผ ์ฌ์ฉํ์ฌ ๋์ ์ผ๋ก ์์ฑ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค:
const myComponent = document.querySelector('my-component');
myComponent.setAttribute('message', 'Updated Message!');
myComponent.setAttribute('country', 'us'); //change the country flag
4. adoptedCallback
adoptedCallback์ ์ปค์คํ
์๋ฆฌ๋จผํธ๊ฐ ์ ๋ฌธ์๋ก ์ด๋๋ ๋ ํธ์ถ๋ฉ๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ฆฌ๋จผํธ๊ฐ ํ iframe์์ ๋ค๋ฅธ iframe์ผ๋ก ์ด๋ํ ๋ ๋ฐ์ํฉ๋๋ค. ์ด ์ฝ๋ฐฑ์ ๋ค๋ฅธ ์๋ช
์ฃผ๊ธฐ ์ฝ๋ฐฑ๋ณด๋ค ๋ ์ฌ์ฉ๋์ง๋ง, ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์ ์ ์ฉํ ์ ์์ต๋๋ค:
- ์ ๋ฌธ์์ ๋ํ ์ฐธ์กฐ ์ ๋ฐ์ดํธ
- ์ ๋ฌธ์์ ์ปจํ ์คํธ์ ๋ฐ๋ผ ์คํ์ผ ์กฐ์
์์ :
class MyComponent extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
}
adoptedCallback(oldDocument, newDocument) {
console.log('Component adopted to a new document!');
console.log('Old Document:', oldDocument);
console.log('New Document:', newDocument);
// Update any document-specific references here
// For example, if you have a reference to a global variable
// in the old document, you might need to update it to the new document's global variable.
}
connectedCallback() {
this.shadow.innerHTML = `
<style>
:host {
display: block;
border: 1px solid #ccc;
padding: 10px;
}
</style>
<p>Hello from MyComponent!</p>
`;
}
}
customElements.define('my-component', MyComponent);
adoptedCallback์ ํธ๋ฆฌ๊ฑฐํ๋ ค๋ฉด, ์๋ฅผ ๋ค์ด ์ปดํฌ๋ํธ๋ฅผ ํ ๋ฌธ์์์ ๋ค๋ฅธ ๋ฌธ์๋ก, ๊ฐ๋ น iframe์ ๋ฌธ์์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์ด๋์์ผ์ผ ํฉ๋๋ค.
์น ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ ๊ด๋ฆฌ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
์น ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ค๋ฃฐ ๋ ๋ช ์ฌํด์ผ ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์๋ DOM ์ฌ์ฉ: ์๋ DOM์ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ์ ๋ด๋ถ ๊ตฌ์กฐ, ์คํ์ผ ๋ฐ ๋์์ ์บก์ํํ์ฌ ์ฃผ๋ณ ๋ฌธ์์์ ์ถฉ๋์ ๋ฐฉ์งํ์ธ์.
- ์์ฑ ๊ด์ฐฐ:
observedAttributesgetter์attributeChangedCallback์ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ ์์ฑ์ ๋ณ๊ฒฝ์ ๋์ํ๊ณ UI๋ฅผ ์ ์ ํ๊ฒ ์ ๋ฐ์ดํธํ์ธ์. - ๋ฆฌ์์ค ์ ๋ฆฌ:
disconnectedCallback์์ ์ด๋ฒคํธ ๋ฆฌ์ค๋, ํ์ด๋จธ, ๋คํธ์ํฌ ์์ฒญ ๋ฑ ์ปดํฌ๋ํธ๊ฐ ์ฌ์ฉํ๋ ๋ชจ๋ ๋ฆฌ์์ค๋ฅผ ์ ๋ฆฌํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์๊ธฐ์น ์์ ๋์์ ๋ฐฉ์งํด์ผ ํฉ๋๋ค. - ์ ๊ทผ์ฑ ๊ณ ๋ ค: ์ ์ ํ ARIA ์์ฑ์ ์ ๊ณตํ๊ณ ์ปดํฌ๋ํธ๊ฐ ํค๋ณด๋๋ก ํ์ ๊ฐ๋ฅํ๋๋ก ํ๋ ๋ฑ ์ ๊ทผ์ฑ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ผ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๋ ์ปดํฌ๋ํธ์ ์ ๊ทผํ ์ ์๋๋ก ๋ณด์ฅํ์ธ์.
- ๋น๋ ๋๊ตฌ ์ฌ์ฉ: Rollup์ด๋ Webpack๊ณผ ๊ฐ์ ๋น๋ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์น ์ปดํฌ๋ํธ๋ฅผ ๋ฒ๋ค๋งํ๊ณ ํ๋ก๋์ ํ๊ฒฝ์ ์ต์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์. ์ด๋ ์ฑ๋ฅ์ ํฅ์์ํค๊ณ ์ปดํฌ๋ํธ์ ํฌ๊ธฐ๋ฅผ ์ค์ด๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ์ฒ ์ ํ ํ ์คํธ: ๋จ์ ๋ฐ ํตํฉ ํ ์คํธ๋ฅผ ๊ตฌํํ์ฌ ๋ค์ํ ์๋๋ฆฌ์ค์์ ์ปดํฌ๋ํธ๊ฐ ์์๋๋ก ์๋ํ๋์ง ํ์ธํ์ธ์. ๋ชจ๋ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ๋ค๋ฃจ๋๋ก ํ ์คํธ๋ฅผ ์๋ํํ์ธ์.
์น ์ปดํฌ๋ํธ ์ค๊ณ๋ฅผ ์ํ ๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ
์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ์น ์ปดํฌ๋ํธ๋ฅผ ์ค๊ณํ ๋๋ ๋ค์ ์ฌํญ์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- ํ์งํ(Localization): ์ฌ๋ฌ ์ธ์ด์ ์ง์ญ์ ์ง์ํ๊ธฐ ์ํด ๊ตญ์ ํ(i18n)๋ฅผ ๊ตฌํํ์ธ์. ๋ฆฌ์์ค ํ์ผ์ด๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒ์ญ์ ๊ด๋ฆฌํ์ธ์. ์๋ฅผ ๋ค์ด, ๋ ์ง ์ ํ๊ธฐ ์ปดํฌ๋ํธ๋ ์ฌ์ฉ์์ ์ ํธ ํ์(์: ๋ฏธ๊ตญ์์๋ MM/DD/YYYY, ์ ๋ฝ์์๋ DD/MM/YYYY)์ผ๋ก ๋ ์ง๋ฅผ ํ์ํด์ผ ํฉ๋๋ค.
- ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ(RTL) ์ง์: ์๋์ด ๋ฐ ํ๋ธ๋ฆฌ์ด์ ๊ฐ์ RTL ์ธ์ด๋ฅผ ์ปดํฌ๋ํธ๊ฐ ์ง์ํ๋์ง ํ์ธํ์ธ์. CSS ๋
ผ๋ฆฌ์ ์์ฑ(์:
margin-left๋์margin-inline-start)์ ์ฌ์ฉํ์ฌ ๋ ์ด์์ ๋ฏธ๋ฌ๋ง์ ์ฒ๋ฆฌํ์ธ์. - ๋ฌธํ์ ๋ฏผ๊ฐ์ฑ: ์ปดํฌ๋ํธ๋ฅผ ๋์์ธํ ๋ ๋ฌธํ์ ์ฐจ์ด๋ฅผ ์ ๋ ํ์ธ์. ํน์ ๋ฌธํ๊ถ์์ ๋ถ์พํ๊ฑฐ๋ ๋ถ์ ์ ํ ์ ์๋ ์ด๋ฏธ์ง๋ ๊ธฐํธ์ ์ฌ์ฉ์ ํผํ์ธ์.
- ์๊ฐ๋ ๋ฐ ํตํ: ๋ ์ง, ์๊ฐ ๋๋ ํตํ๋ฅผ ํ์ํ ๋๋ ์ฌ์ฉ์์ ํ์ง ์๊ฐ๋์ ํตํ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Intl๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ๊ฐ์ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ํํ์ธ์. - ์ ๊ทผ์ฑ: WCAG ๊ฐ์ด๋๋ผ์ธ์ ์ค์ํ์ฌ ์ ์ธ๊ณ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๊ฐ ์ปดํฌ๋ํธ์ ์ ๊ทผํ ์ ์๋๋ก ๋ณด์ฅํ์ธ์.
๊ฒฐ๋ก
์น ์ปดํฌ๋ํธ ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ดํดํ๋ ๊ฒ์ ๊ฒฌ๊ณ ํ๊ณ , ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ, ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ํ์์ ์ ๋๋ค. ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ์ ํ์ฉํ์ฌ ์ปดํฌ๋ํธ์ ์ํ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ , ๋ณํ์ ๋์ํ๋ฉฐ, ๋ฆฌ์์ค๋ฅผ ์ ๋ฆฌํ ์ ์์ต๋๋ค. ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๊ณ ๊ธ๋ก๋ฒ ์์๋ฅผ ๊ณ ๋ คํจ์ผ๋ก์จ ์ ์ธ๊ณ ์ฌ์ฉ์๋ค์ด ์ ๊ทผํ๊ณ ์ฌ์ฉํ ์ ์๋ ์น ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์น ๊ฐ๋ฐ์ด ๊ณ์ ๋ฐ์ ํจ์ ๋ฐ๋ผ, ์น ์ปดํฌ๋ํธ๋ ๋ณต์กํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ์ ์ ๋ ์ค์ํ ์ญํ ์ ํ ๊ฒ์ ๋๋ค. ์ด๋ฅผ ๋ฐ์๋ค์ด๊ณ , ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ง์คํฐํ์ฌ ๊ทธ ์ ์ฌ๋ ฅ์ ์ต๋ํ ํ์ฉํ์ธ์!